package com.g7.dsp.util.testcase;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class TxtToExcel {
	  private static List<String> title = new ArrayList();
	  private static WritableWorkbook wwb;
	  private static WritableSheet ws;
	  private static Element root;
	  private static String module_name = null;
	  private static String sub_module_name = null;
	  private static Element ppelement = null;
	  private static Boolean tmpBol = Boolean.valueOf(false);

	  public static void transferXMLToExcel(String oldfilename)
	  {
	    File f = new File(oldfilename);
	    String newfilename = null;
	    try {
	      newfilename = getExcelName(oldfilename, ExcelToXml.getNow());
	    }
	    catch (ParseException e1) {
	      e1.printStackTrace();
	    }
	    System.out.println("newfilename:" + newfilename);
	    System.out.println("converting,please wait...");

	    module_name = null;
	    sub_module_name = null;
	    ppelement = null;

	    title.add("用例名称");
	    title.add("预置条件");
	    title.add("操作步骤");
	    title.add("预期结果");
	    title.add("测试方式");
	    title.add("用例等级");
	    title.add("摘要");
	    title.add("自定义字段");
	    title.add("关键字");

	    SAXReader reader = new SAXReader();
	    try
	    {
	      Document doc = reader.read(f);
	      root = doc.getRootElement();

	      if (root.getName().equals("testcases")) {
	        forEachElement(root, newfilename);
	      }
	      else if (root.getName().equals("testsuite")) {
	        title.add(0, "子模块");
	        title.add(0, "模块");
	        tmpBol = Boolean.valueOf(true);
	        forEachElement(root, newfilename);
	      }
	      title.clear();
	    }
	    catch (DocumentException e) {
	      e.printStackTrace();
	    }
	    catch (Exception e) {
	      e.printStackTrace();
	    }
	  }

	  private static void forEachElement(Element element, String newfilename)
	    throws Exception
	  {
	    List testcase = null;

	    for (Iterator it = element.elementIterator(); it.hasNext(); ) {
	      Element subelement = (Element)it.next();
	      String text = subelement.getName();

	      if (text.equals("testsuite")) {
	        forEachElement(subelement, newfilename);
	      }
	      else if (text.equals("testcase")) {
	        if (!tmpBol.booleanValue()) {
	          testcase = parseTestCaseTag(subelement, null, null);
	        }
	        else
	        {
	          String rootname = root.attributeValue("name");
	          Element sup_element = element.getParent();
	          if ((element.equals(root)) && (!rootname.equals(""))) {
	            module_name = rootname;
	            sub_module_name = "";
	          }
	          else if ((sup_element.equals(root)) && (sup_element.attributeValue("name").equals(""))) {
	            if (ppelement == null) {
	              ppelement = sup_element;
	            }
	            module_name = element.attributeValue("name");
	            sub_module_name = "";
	          } else {
	            sub_module_name = element.attributeValue("name");

	            if (ppelement == null) {
	              ppelement = sup_element;
	            }
	            if (module_name == null) {
	              module_name = getModuleName(sup_element);
	            }

	            if (!sup_element.equals(ppelement)) {
	              module_name = getModuleName(sup_element);
	              ppelement = sup_element;
	            }
	          }
	          testcase = parseTestCaseTag(subelement, module_name, sub_module_name);
	        }

	        writeExcelByLine(newfilename, testcase);
	      }
	    }
	  }

	  private static String getModuleName(Element sup_element) {
	    StringBuffer temp = new StringBuffer();
	    List suite_names = new ArrayList();

	    Element supe = sup_element;
	    while (!supe.equals(root)) {
	      suite_names.add(supe.attributeValue("name"));
	      supe = supe.getParent();
	    }

	    String str = "";
	    try {
	      str = supe.attributeValue("name");
	    }
	    catch (NullPointerException e) {
	      str = "";
	    }
	    if ((str != null) && (!str.equals(""))) {
	      suite_names.add(str);
	    }
	    Collections.reverse(suite_names);
	    for (int i = 0; i < suite_names.size(); i++) {
	      temp.append((String)suite_names.get(i));
	      if (i != suite_names.size() - 1) {
	        temp.append("/");
	      }
	    }
	    return temp.toString();
	  }

	  private static List<String> parseTestCaseTag(Element subelement, String module_name, String sub_module_name)
	  {
	    List testcase = new ArrayList();

	    if ((module_name != null) && (sub_module_name != null)) {
	      testcase.add(replace(module_name));
	      testcase.add(replace(sub_module_name));
	    }

	    String casename = subelement.attributeValue("name");
	    String preconditions = subelement.elementText("preconditions");
	    String execution_type = subelement.elementText("execution_type");

	    testcase.add(replace(casename));
	    testcase.add(replace(preconditions));

	    Element steps = subelement.element("steps");
	    if (steps != null) {
	      List step = steps.elements("step");
	      StringBuffer actions = new StringBuffer();
	      StringBuffer expectedresults = new StringBuffer();
	      for (int i = 0; i < step.size(); i++)
	      {
	        actions.append(((Element)step.get(i)).elementText("actions"));
	        expectedresults.append(((Element)step.get(i)).elementText(
	          "expectedresults"));
	      }

	      if (step.size() != 0) {
	        testcase.add(replace(actions.toString()));
	        testcase.add(replace(expectedresults.toString()));
	      } else {
	        testcase.add("");
	        testcase.add("");
	      }
	    } else {
	      testcase.add("");
	      testcase.add("");
	    }
	    if (execution_type.equals("1"))
	      execution_type = "手工";
	    else if (execution_type.equals("2")) {
	      execution_type = "自动化";
	    }
	    testcase.add(replace(execution_type));

	    String importance = subelement.elementText("importance");
	    if (importance.equals("1"))
	      importance = "低";
	    else if (importance.equals("2"))
	      importance = "中";
	    else if (importance.equals("3")) {
	      importance = "高";
	    }
	    testcase.add(replace(importance));

	    String summary = subelement.elementText("summary");
	    testcase.add(replace(summary));
	    Element custom_fields = subelement.element("custom_fields");
	    if (custom_fields != null) {
	      List fileds = custom_fields.elements("custom_field");
	      StringBuffer filedsbuf = new StringBuffer();
	      for (int i = 0; i < fileds.size(); i++)
	      {
	        if (!((Element)fileds.get(i)).elementText("value").isEmpty()) {
	          filedsbuf.append(((Element)fileds.get(i)).elementText("name") + ":" + ((Element)fileds.get(i)).elementText("value").replace("\n", "") + "\n");
	        }
	      }
	      if (fileds.size() != 0)
	        testcase.add(replace(filedsbuf.toString()));
	      else
	        testcase.add("");
	    }
	    else {
	      testcase.add("");
	    }
	    Element keywords_ele = subelement.element("keywords");
	    if (keywords_ele != null) {
	      List keywords = keywords_ele.elements("keyword");
	      StringBuffer filedsbuf = new StringBuffer();
	      for (int i = 0; i < keywords.size(); i++)
	      {
	        filedsbuf.append(((Element)keywords.get(i)).attributeValue("name") + ":" + ((Element)keywords.get(i)).elementText("notes").replace("\n", "") + "\n");
	      }
	      if (keywords.size() != 0)
	        testcase.add(replace(filedsbuf.toString()));
	      else
	        testcase.add("");
	    }
	    else {
	      testcase.add("");
	    }
	    return testcase;
	  }

	  private static void writeExcelByLine(String newfilename, List<String> testcase)
	    throws Exception
	  {
	    File file = new File(newfilename);

	    if (!file.exists())
	    {
	      try {
	        wwb = Workbook.createWorkbook(file);

	        ws = wwb.createSheet("TestCase", 0);
	      }
	      catch (IOException e) {
	        e.printStackTrace();
	      }

	      for (int i = 0; i < title.size(); i++) {
	        Label label0 = new Label(i, 0, (String)title.get(i));
	        Label label = new Label(i, 1, (String)testcase.get(i));
	        ws.addCell(label0);
	        ws.addCell(label);
	      }

	      wwb.write();
	      wwb.close();
	    }
	    else {
	      Workbook twb = Workbook.getWorkbook(file);

	      wwb = Workbook.createWorkbook(file, twb);

	      ws = wwb.getSheet(0);

	      int num = ws.getRows();
	      for (int i = 0; i < title.size(); i++) {
	        Label label = new Label(i, num, (String)testcase.get(i));
	        ws.addCell(label);
	      }

	      wwb.write();
	      wwb.close();
	      twb.close();
	    }
	  }

	  private static String getExcelName(String oldfilename, String time)
	  {
	    String newfilename = "";
	    String[] temp = oldfilename.split("\\\\");
	    String prename = temp[(temp.length - 1)].substring(0, 
	      temp[(temp.length - 1)].length() - 4);
	    newfilename = oldfilename
	      .substring(0, oldfilename.length() - 
	      temp[(temp.length - 1)].length()) + 
	      prename + "_" + time + ".xls";

	    return newfilename;
	  }

	  private static String replace(String oldStr)
	  {
	    if (oldStr != null) {
	      String newStr = "";
	      newStr = oldStr.replaceAll("</br>", "\r\n");
	      newStr = newStr.replaceAll("</p>", "\r\n");
	      newStr = newStr.replaceAll("<([^>]*)>", "");
	      newStr = newStr.replaceAll("&\\w*;", "");
	      return newStr;
	    }
	    return "";
	  }
}
